﻿package com.map 
{
	import com.element.Clips;
	import com.element.Tile;
	import com.event.EventZheng;
	import com.staticInfo.EventConst;
	import com.staticInfo.MapData;
	import flash.display.Sprite;
	import flash.geom.Point;
	
	/**
	 * ...
	 * @author zhengzihua
	 */
	public class SetObjectIndex implements IMap
	{
		//seekRoad需要用到的变量
		private var openList:Array;
		private var closeList:Object;
		private var targetP:Point;
		private var _c:Array;
		//---------------------------
		public function SetObjectIndex() 
		{
			
		}
		public function setObjectIndex(thingsArr:Array,objContain:Sprite):void {
			//thingsArr.sortOn(["sx","sy"], [Array.NUMERIC,Array.NUMERIC|Array.DESCENDING]);
			thingsArr.sortOn("y", Array.NUMERIC);
			var i:int = 0;
			var num:int = thingsArr.length;
			while (i < num && num > 1) {		
				var clips:Clips = thingsArr[i] as Clips;
				clips.level = i;
				objContain.setChildIndex(clips, i);
				i++;
			}
		}
		public function drawMap(tileContain:Sprite, row:int, cols:int, alertArray:Array):Sprite {
			for (var k:int = 0; k < row; k++ ) {
				alertArray.push(new Array(cols));
			}
			for(var i:int=0;i<row;i++){
				for (var j:int = 0; j < cols; j++) {
					alertArray[i][j] = 0;
					var tile:Tile=new Tile();
					tile.x = (i + j) * MapData.basePix;
					tile.y = (i - j) * MapData.basePix * 0.5;
					tile.point = new Point(i, j);
					tile.name = "t"+i + "_" + j;
					tileContain.addChild(tile);
				}
			}	
			return tileContain;
		}
		public function seekRoad(sp:Point, ep:Point, alertArr:Array,dispatcherContain:Sprite ):void {
			var roadEvent:EventZheng = new EventZheng(EventConst.EVENT_MAP_MAIN);
			roadEvent.obj.type = "seekRoad";
			var path:Array = [];//最后形成的路径
			var contain:Sprite = dispatcherContain;
			_c = alertArr;
			if (_c[ep.x][ep.y] == 1) {
				roadEvent.obj.roadPath = path;
				roadEvent.obj.info="目标点有障碍物。"
				contain.parent.dispatchEvent(roadEvent);//抛出信息
				return;
			}
			openList = [];
			closeList = { };
			targetP = ep;
			
			
			var ix:int = sp.x;
			var iy:int = sp.y;
			var sign:Sign = new Sign(sp,ix,iy,null);//定义开始标记
			
			while (true) {
				//将当前标记的周围八个标记添加到openlist中
				addCloseList(createSign(ix -1, iy - 1, true, sign));
				addCloseList(createSign(ix -1, iy, false, sign));
				addCloseList(createSign(ix -1, iy+1, true, sign));
				addCloseList(createSign(ix, iy + 1, false, sign));
				addCloseList(createSign(ix + 1, iy + 1, true, sign));
				addCloseList(createSign(ix + 1, iy, false, sign));
				addCloseList(createSign(ix + 1, iy - 1, true, sign));
				addCloseList(createSign(ix, iy - 1, false, sign));	
		
				//将当前标记改为openlist中权值最小的标记
				openList.sortOn("f", Array.NUMERIC);
				//将当前标记添加到closelist中
				closeList[ix + "_" + iy] = sign;
				sign = openList.shift();//选出新的参考点
				ix = sign.ix;
				iy = sign.iy;
				//退出循环的条件
				//如果当前标记是结束点
				if (ix == ep.x && iy == ep.y) {
					while(sign){
						path.push(sign.getSign());
						sign = sign.p;
					}
					break;
				}
				//如果openlist列表已经空了
				if (openList.length == 0) {
					break;
				}
			}
			sign = null;

			path = path.reverse();
			roadEvent.obj.roadPath = path;
			roadEvent.obj.info="路径查找完毕。"
			contain.parent.dispatchEvent(roadEvent);//抛出找到路径的信息
		}
		private function addCloseList(sign:Sign):void {
			if (sign) {
				openList.push(sign);
				openList[sign.ix + "_" + sign.iy] = sign;
			}
		}
		private function createSign(ix:int, iy:int, slop:Boolean, pSign:Sign):Sign {//创建当前标记周围的八个标记
			//不属于地图的标记，不要添加		
			if (ix < 0 || iy < 0 || ix >= _c.length || iy >= _c[0].length) {
				return null;	
			}
			//标记有障碍物的，不要添加
			if (_c[ix][iy] == 1) {
				return null;
			}
			//已经在openlist中的，不要添加
			if (openList[ix + "_" + iy] != null) {
				return null;
			}
			//已经在closelist中的，不要添加
			if(closeList[ix + "_" + iy] != null) {
				return null;
			}
			//如果是当前标记的斜位，那么判断其上下左右是否有障碍物，或者不属于地图，如果是，不要添加
			if (slop) {
				if (_c[pSign.ix][iy] == 1 || _c[ix][pSign.iy] == 1) {
					return null;
				}
			}
			var cx:int = Math.abs(ix - targetP.x);
			var cy:int = Math.abs(iy - targetP.y);
			var ng:int;
			if (slop) {
				ng = pSign.ng + MapData.slopValue;
			}else {
				ng = pSign.ng + MapData.rightValue;
			}	
			
			//估价
			var diag:int = Math.min(cx, cy);
			var cos:int = diag * MapData.slopValue + (cx + cy - 2 * diag) * MapData.rightValue;
			return new Sign(new Point(ix,iy),ng, cos, pSign);
			//return new Sign(new Point(ix,iy),ng, (cx + cy) * 10, pSign);
		}
	}
	
}